<?php
/**
 * 路由
 * 
 * @package SFramework
 * @author Shuky
 * @since v1.0
 * @version $Id: Router.php 82 2010-12-23 18:23:35Z shukyoo@gmail.com $
 */
namespace SFramework;

class Router
{
    /**
     * @var Request
     */
    protected $_request = null;
    
    // 自身单件实例类
    protected static $_instance = null;
    
    // 模块
    protected $_module = 'home';
    
    // 控制
    protected $_controller = 'index';
    
    // 动作
    protected $_action = 'index';
    
    
    /**
     * 自身单件实例获取
     */
    public static function getInstance()
    {
    	if (null === self::$_instance) {
    		self::$_instance = new self();
    	}
    	return self::$_instance;
    }
    
    
    /**
     * 构造，按/module/controller/action方式解析请求
     * @todo 注意一下这里跟parseLink的纠结，如何去统一提取规则
     */
    protected function __construct()
    {
    	$path = $this->getRequest()->getPathInfo();
		$path = explode('/', $path);
		if (!empty($path[0])) {
			$this->_module = trim(strtolower($path[0]));
		}
		if (!empty($path[1])) {
			$this->_controller = trim(strtolower($path[1]));
		}
		if (!empty($path[2])) {
			$this->_action = trim(strtolower($path[2]));
		}
    }
    
    
    /**
     * 按规则处理路径串
     * 路径格式：module/controller/action
     * 默认以此格式作为链接样式
     * 返回绝对Url路径
     */
    public function parseLink($path)
    {
        if (strpos($path, '/') === 0) {
        	$path = substr($path, 1);
        }
    	return $this->getRequest()->getBaseUrl() .'/'. $path;
    }
    
    
    /**
     * 获取请求
     * @return Request
     */
    public function getRequest()
    {
        if (null === $this->_request) {
    		$this->_request = Request::getInstance();
    	}
    	return $this->_request;
    }
    
    
    /**
     * 路由解析和导向
     */
    public function dispatch()
    {	    
	    $controlClass = 'APP\\'. ucfirst($this->_module) .'\\Controllers\\'. ucfirst($this->_controller);
	    if (!class_exists($controlClass)) {
	    	$this->notFound();
	    }
		$controlClass = new $controlClass();
		$action = $this->_action .'Action';
		if (!method_exists($controlClass, $action)) {
			$this->notFound();
		}
		$controlClass->$action();
    }
    
    
    /**
     * 404导向
     */
    public function notFound($toUrl = '/home/notfound')
    {
    	$this->redirect($toUrl);
    }
    
    
    /**
     * 转向
     */
	public function redirect($toUrl)
	{
	    $toUrl = (strpos($toUrl, 'http://') === false) ? $this->parseLink($toUrl) : $toUrl;
		header('Location: '. $toUrl);
	}
	
	
	/**
	 * 处理请求参数
	 */
	public function mergeQuery($url, $params)
	{
	    $query = parse_url($url, PHP_URL_QUERY);
		$query = parse_str($query, $queryArr);
		$queryArr = array_merge($queryArr, $params);
		$pa = array();
		foreach ($queryArr as $k=>$v) {
		    if ($v !== '') {
		    	$pa[] = $k .'='. $v;
		    }
		}
		$query = implode('&', $pa);
		$pos = strpos($url, '?');
		$url = ($pos === false ? $url : substr($url, 0, $pos)) . ($query ? '?'. $query : '');
		return $url;
	}
	
	
	/**
	 * 获取Module
	 */
	public function getModule()
	{
		return $this->_module;
	}
	
	
	/**
	 * 获取Controller
	 */
	public function getController()
	{
		return $this->_controller;
	}
	
	
	/**
	 * 获取Action
	 */
	public function getAction()
	{
		return $this->_action;
	}


	/**
	 * 设置Action
	 */
	public function setAction($action)
	{
		$this->_action = $action;
	}
}